package server.buscador;

import java.awt.geom.Point2D.Float;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import javax.swing.JFileChooser;

import editor.modelo.Floor;
import editor.modelo.JSONConverter;
import editor.modelo.LandMark;
import editor.modelo.ModelUtilities;
import editor.modelo.Portal;
import editor.modelo.Portal.Clase;
import editor.modelo.Space;


public class AStar {

	protected List<SpaceNode> espacios; //todos los espacios en forma plana

	protected ArrayList<Floor> pisos; //los pisos a su vez apuntan a los mismos espacios

	//protected ArrayList<"Edicio"> edificios; //por ahora es solo Alem. Hay que hacer esta clase

	public List<SpaceNode> getEspacios(){
		return espacios;
	}

	public static void main (String args[]){
		AStar a = new AStar();
		//	a.search("6A", "38B");
		ANode res = a.search("ArribaAula44", "B");
		System.out.println("el camino hallado es: ");
		for(SpaceNode s : res.camino){
			System.out.println(s.getName()+ " ");
		}
		System.out.println(res.nodo.getName());

	}


	public AStar(){
		espacios = new ArrayList<SpaceNode>();

		pisos = ModelUtilities.loadBuilding(getWorkingDir(), new JSONConverter(3));
		int i = 0;

		for (Floor f : pisos) {
			for(Space s: f.getEspacios() ){
				espacios.add((SpaceNode)s);
				((SpaceNode)s).setPisoPadre(f);
				((SpaceNode)s).setPosition(i++);//para busqueda lineal
			}
			for(LandMark lm: f.getLandmarks()){
				SpaceNode sn = getSpaceFromLandMark(lm);
				sn.setPisoPadre(f);
				sn.setPosition(i++);
				((SpaceNode)lm.getSpace()).addPortal(new NodeEdge(sn, ((SpaceNode)lm.getSpace())));
				espacios.add(sn);
				//sn.addPortal(new NodeEdge(lm, sn));
			}
			for(Portal p: f.getPortales()){
				SpaceNode src = (SpaceNode) p.getSource();
				if(p.getClase() == Clase.intra_floor){
					//SpaceNode src = (SpaceNode) p.getSource();
					src.addPortal(new NodeEdge(p));
					if(p.isBidirectional()){
						src = (SpaceNode) p.getTarget();
						Portal p2 = p.getInvertedPortal();
						src.addPortal(new NodeEdge(p2));
					}
				}else{
					//En portales externos, bidireccional significa si se puede salir por ahi
					if(p.isBidirectional()){
						src.addPortal(new NodeEdge(p));
					}
				}	
			}
		}
	}


	private SpaceNode getSpaceFromLandMark(LandMark lm) {
		SpaceNode s = new SpaceNode();
		s.setCentro((Float) lm.getCentro());
		s.setName(lm.getName());
		s.setHeight(lm.getSpace().getHeight());
		
		return s;
	}

	private File getWorkingDir() {
		FileInputStream fis;
		InputStreamReader in;
		String s= ".";
		try {
			fis = new FileInputStream("./res.txt"); 

			in = new InputStreamReader(fis, "UTF-8");

			BufferedReader input =  new BufferedReader(in);
			s = input.readLine();
			fis.close();
			in.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		JFileChooser jfc = new JFileChooser(s);
		jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		jfc.setVisible(true);
		int returnVal = jfc.showOpenDialog(null);
		if(returnVal == JFileChooser.APPROVE_OPTION){
			FileOutputStream fos;
			OutputStreamWriter out;
			try {
				File f = new File("./res.txt");
				System.out.println(f.getAbsolutePath());
				f.createNewFile();
				fos = new FileOutputStream(f, false);

				out = new OutputStreamWriter(fos, "UTF-8");
				out.write(jfc.getSelectedFile().toString());
				out.close();

			} catch (Exception e) {

				e.printStackTrace();
			} 
		}
		return jfc.getSelectedFile();

	}

	public ANode search(String idInitial, String idGoal){
		SpaceNode ini = null;
		SpaceNode meta = null;
		for (SpaceNode n : espacios) {
			if(n.getName().equals(idInitial)){
				ini = n;
			}
			if(n.getName().equals(idGoal)){
				meta = n;
			}
			if(ini != null && meta != null) 
				return new AStarSearch().search(ini, meta);//recorre el grafo, pero no lo tiene completo

		}
		System.out.println("no se encontraron los nodos a buscar");
		return null;
	}


}
